import { Injectable } from '@nestjs/common';
import { JwtService, JwtSignOptions, JwtVerifyOptions } from '@nestjs/jwt';

@Injectable()
export class JwtVerifyService {
    private secretLen = 15;
    private pos = 5;

    constructor(private jwtService:JwtService) {
        
    }

    sign(payload: Buffer | object, expire:number) : string{
         //生成token

        const secret = this.getRandomNChars(this.secretLen)

        let token = this.jwtService.sign(payload, {
            secret,
            expiresIn : expire
        })
        
        return this.mixUp(token, secret)
    }


    verify(token: string) : any{ //验证token
        try {
            if (token === null) return null;
    
            const tokens = token.split(",");
            const tokenStr1 = tokens[1];
            const tokenStr2 = tokens[2];
        
            const str1 = tokenStr1.substring(this.pos, this.pos + this.pos + this.secretLen);
        
            tokens[1] = tokenStr1.substring(0, this.pos) + tokenStr1.substring(this.pos + this.pos + this.secretLen);
            tokens[2] = tokenStr2.substring(0, this.pos) + tokenStr2.substring(this.pos + this.pos);
        
            token = tokens.join(".");

            const secret = str1.substring(0, this.secretLen)

            return this.jwtService.verify(token, {
                secret
            })
            
        } catch (error) {
            
        }


        return null
    }


    getRandomNChars(n) {
        const randomString = "1qwZYeX2rTtCSDFGHJKLy3m4V5uU6B7ioNp89aMRxvnASDFsdfgQh0WEjIkl";
        let characters = [...randomString];
        for (let i = characters.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [characters[i], characters[j]] = [characters[j], characters[i]];
        }
    
        const result = new Array(n).fill(null);
        for (let i = 0; i < n; i++) {
          const index = Math.floor(Math.random() * characters.length);
          result[i] = characters[index];
        }
        return result.join('');
    }
    
    mixUp(token:string, secret:string) {
        const str1 = secret + this.getRandomNChars(this.pos);
        const str2 = this.getRandomNChars(this.pos);
    
        const tokens = token.split('.');
        const tokenStr1 = tokens[1];
        const tokenStr2 = tokens[2];
    
        tokens[1] = tokenStr1.substring(0, this.pos) + str1 + tokenStr1.substring(this.pos);
        tokens[2] = tokenStr2.substring(0, this.pos) + str2 + tokenStr2.substring(this.pos);
    
        return tokens.join(',');
    }
    
}
